#include "StatusBar.h"

namespace Dicewars
{
	StatusBar::StatusBar(void)
	{
		for (int t = 0; t < 6; t++)
		{
			char* image = NULL;
			std::ostringstream c;
			c << (t+1);
			std::string filename = "data/die" + (c.str()) + ".png";
			textures.push_back(new PNGTexture(c.str(), filename.c_str()));
		}
		cpuIndicator = new PNGTexture("cpu", "data/cpu.png");
		userIndicator = new PNGTexture("user", "data/user.png");
	}

	StatusBar::~StatusBar(void)
	{
	}

	void StatusBar::SetOrtho()
	{
		glMatrixMode (GL_PROJECTION);
		glPushMatrix ();
		glLoadIdentity ();
		gluOrtho2D (0.0, 10.0, -10.0, 0.0);
		glMatrixMode (GL_MODELVIEW);	
	}

	void StatusBar::ResetView ()
	{
		glMatrixMode (GL_PROJECTION);
		glPopMatrix ();
		glMatrixMode (GL_MODELVIEW);
	}

	void StatusBar::CreateBar ()
	{
		glPushMatrix ();
		glLoadIdentity ();
		glColor4f (0.1, 0.1, 0.1, 0.8);
		glRectf(0.0, 0.0, 10.0, -1.5);
		CreateTimeCounter ();
		CreateDiceCounter ();
		glPopMatrix ();
		glPushMatrix ();
		glColor4f (0.1, 0.1, 0.1, 0.8);
		CreatePlayerIndicator();
		glPopMatrix();
	}

	void StatusBar::CreateTimeCounter ()
	{
		const float orthoWidth = 5.0;
		const float tick = orthoWidth/(float)30;
		glPushMatrix ();
		glLoadIdentity ();
		glColor4f (counterColor[0], counterColor[1], counterColor[2], 0.6);
		for (int i=0; i < currentCounterValue; i++)
		{
			glRectf(0.0, -0.4, tick*0.90, -1.2);
			glTranslatef(tick, 0.0, 0.0);
		}	
		glPopMatrix ();
	}

	void StatusBar::Draw ()
	{
		SetOrtho ();
		glDisable (GL_DEPTH_TEST);
		glEnable (GL_BLEND);
		glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		CreateBar ();
		glDisable (GL_BLEND);
		glEnable (GL_DEPTH_TEST);
		ResetView ();
	}

	void StatusBar::CreateDiceCounter()
	{
		const float aspectRatio = glutGet(GLUT_WINDOW_WIDTH)/(float)glutGet(GLUT_WINDOW_HEIGHT);
		const float orthoWidth = 5.0;
		const float tick = orthoWidth/(float)8;
		float pos = orthoWidth + tick;
		glPushMatrix();
		glLoadIdentity();
		glTranslatef (pos, -0.1, 0.0);
		glScalef(0.4, 0.4, 1.0);
		glEnable(GL_TEXTURE_2D);
		glPushMatrix();
		for(diceIterator = attackResult.dice.begin(); diceIterator != attackResult.dice.end(); ++diceIterator)
		{
			glColor3fv (attackerColor);
			if (*diceIterator != 0)
			{
				glBindTexture(GL_TEXTURE_2D, textures.at((*diceIterator)-1)->GetId());
				glBegin(GL_QUADS);
					glTexCoord2f(0.0, 1.0);	glVertex2f(0.0, 0.0);
					glTexCoord2f(0.0, 0.0);	glVertex2f(0.0, -aspectRatio);
					glTexCoord2f(1.0, 0.0);	glVertex2f(1.0, -aspectRatio);
					glTexCoord2f(1.0, 1.0);	glVertex2f(1.0, 0.0);
				glEnd();
			}
			glTranslatef(2*tick, 0, 0);
		}
		glPopMatrix();
		glTranslatef(0, -2.5*tick, 0);
		glPushMatrix();
		for(diceIterator = defendResult.dice.begin(); diceIterator != defendResult.dice.end(); ++diceIterator)
		{
			glColor3fv (defenderColor);
			if (*diceIterator != 0)
			{
				glBindTexture(GL_TEXTURE_2D, textures.at((*diceIterator)-1)->GetId());
				glBegin(GL_QUADS);
					glTexCoord2f(0.0, 1.0);	glVertex2f(0.0, 0.0);
					glTexCoord2f(0.0, 0.0);	glVertex2f(0.0, -aspectRatio);
					glTexCoord2f(1.0, 0.0);	glVertex2f(1.0, -aspectRatio);
					glTexCoord2f(1.0, 1.0);	glVertex2f(1.0, 0.0);
				glEnd();
			}
			glTranslatef(2*tick, 0, 0);
		}
		glPopMatrix();
		glDisable(GL_TEXTURE_2D);
		if(ConfigSingleton::Instance()->GetShowFPS())
		{
			std::string wireframeName = std::string("Polygon Mode");
			std::string wireframe = ConfigSingleton::Instance()->GetWireframe() ? "Wireframe (F3)" : "Fill (F3)";
			std::string renderMode = "";
			switch(ConfigSingleton::Instance()->GetRenderMode())
			{
				case RenderVBO:
				{
					renderMode = "VBO (Befehlsargument)";
					break;
				}
				case RenderImmediate:
				{
					renderMode = "Immediate (F7)";
					break;
				}
				case RenderDisplayList:
				{
					renderMode = "DisplayList (F7)";
					break;
				}
			}
			std::string frustumCulling = ConfigSingleton::Instance()->GetFrustumCulling() ? "activated (F8)" : "deactivated (F8)";
			std::string renderModeName = std::string("Render Mode:");
			std::string frustumCullingName = std::string("Frustum Culling:");
			std::string fpsName = std::string("FPS:");
			DrawText(wireframeName, wireframe, 0.5, -8.0);
			DrawText(frustumCullingName, frustumCulling, 0.5, -8.5);
			DrawText(renderModeName, renderMode, 0.5, -9.0);
			DrawText(fpsName, (int)FPS, 0.5, -9.5);
		}

		glPopMatrix();
	}
	
	void StatusBar::SetActivePlayeryType(PlayerType newPlayerType)
	{
		playerType = newPlayerType;
	}
	
	void StatusBar::CreatePlayerIndicator()
	{
		switch(playerType)
		{
			case HumanPlayer:
			{
				DrawText("","Player", 4.5, -0.9);
				break;
			}
			case ComputerPlayer:
			{
				DrawText("","CPU", 4.5, -0.9);
				break;
			}
		}
	}

	void StatusBar::DrawText(std::string name, std::string value, float positionX, float positionY)
	{	
		glLoadIdentity();
		char str[200];
		glColor4f(1.0, 1.0, 1.0, 0.5);
		char *t = str;
		sprintf(str, "%s  %s", name.c_str(), value.c_str());
		glRasterPos2f(positionX, positionY);
		for(t; *t != '\0'; t++)
		{
			glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *t);
		}
	}

	void StatusBar::DrawText(std::string name, int value, float positionX, float positionY)
	{	
		glLoadIdentity();
		char str[200];
		glColor4f(1.0, 1.0, 1.0, 0.5);
		char *t = str;
		sprintf(str, "%s  %d (F2)", name.c_str(), value);
		glRasterPos2f(positionX, positionY);
		for(t; *t != '\0'; t++)
		{
			glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *t);
		}
	}

	void StatusBar::SetFPS(float fps)
	{
		FPS = fps;
	}

	void StatusBar::SetTimeCounterValue (int value)
	{
		currentCounterValue = value;
	}

	void StatusBar::SetTimeCounterColor(float r, float g, float b)
	{
		counterColor[0] = r;
		counterColor[1] = g;
		counterColor[2] = b;
	}

	void StatusBar::SetDiceCounterValues(GameStatus att, GameStatus def)
	{
		memcpy(attackerColor, att.color, 3*sizeof(float));
		memcpy(defenderColor, def.color, 3*sizeof(float));
		attackResult = att;
		defendResult = def;
	}
}